Kenny’s Computational Musicology Portofolio Repository
For my corpus I’ll be looking at the music catalog of the three top best selling female R&B musicians, namely Beyoncé, Mariah Carey and Rihanna. They share a lot of similarities but also some compelling differences, such as the records they’ve broken, their cultural backgrounds, vocal capabilities and the genres that influence their music.
This means that there are many interesting angles that could be investigated such as how Mariah and Rihanna have way more no 1 hits in their career than Beyoncé. In contrast Beyoncé has 32 grammy’s to her name which is the all-time record for most grammy wins, Rihanna has 9 awards while Mariah has 5. Mariah and Beyoncé are also widely regarded to be much better vocalists than Rihanna, but Rihanna is the one who has sold the most records out of the three of them. There are very peculiar differences in the career milestones they’ve achieved and I want to see if those differences can be explained by comparing their music, and find out if they’re really all that different from each-other or actually the same.
I think my corpus is representative of the artists I want to compare, one weakness would be that at certain points of her career Rihanna’s live vocals were not as of equal quality to her studio versions, but those live vocals are also not available on Spotify. I think my other challenge also lies in the fact that Mariah has started her career before Rihanna and Beyoncé and thus also has music that is typical of certain eras that Rihanna and Beyoncé don’t, I also see this as an opportunity since some of Mariah’s older Christmas album still manage to chart every decade so while it is a challenge it also presents interesting opportunities for comparison. All I want for Christmas by Mariah is thus also one her most interesting tracks which became a number 1 hit in 2019 25 years after it was released. Rihanna with songs like S&M and Rude Boy which have very controversial lyrics and don’t seem to be specifically tailored for a massive audience but are still songs that still managed to peak at No. 1. Finally Beyoncé who has a lot of hits that champion female empowerment.
All wildly different strategies that seem to work but I want to find out if the music itself is really all that different. Another interesting aspect is comparing their fanbases to see how much overlap there is between them.
library(tidyverse) library(spotifyr) library(compmus) library(plotly) library(conflicted)
bmr <- get_playlist_audio_features(’‘,’2uzoyXBjDGEEpwAEMVfuB3’)
bmr %>% ggplotB(
aes( x = danceability, y = tempo, size = track.popularity, colour =
track.artists$name ) ) + geom_point() + scale_size_continuous(
trans = “exp”,)
{r}
{r} ### Chordogram - Emotions
library(tidyverse) library(spotifyr) library(compmus) library(conflicted)
circshift <- function(v, n) { if (n == 0) v else c(tail(v, n), head(v, -n)) }
major_chord <- c( 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0) minor_chord <- c( 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0) seventh_chord <- c( 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0)
major_key <- c(6.35, 2.23, 3.48, 2.33, 4.38, 4.09, 2.52, 5.19, 2.39, 3.66, 2.29, 2.88) minor_key <- c(6.33, 2.68, 3.52, 5.38, 2.60, 3.53, 2.54, 4.75, 3.98, 2.69, 3.34, 3.17)
chord_templates <- tribble( ~name, ~template, “Gb:7”, circshift(seventh_chord, 6), “Gb:maj”, circshift(major_chord, 6), “Bb:min”, circshift(minor_chord, 10), “Db:maj”, circshift(major_chord, 1), “F:min”, circshift(minor_chord, 5), “Ab:7”, circshift(seventh_chord, 8), “Ab:maj”, circshift(major_chord, 8), “C:min”, circshift(minor_chord, 0), “Eb:7”, circshift(seventh_chord, 3), “Eb:maj”, circshift(major_chord, 3), “G:min”, circshift(minor_chord, 7), “Bb:7”, circshift(seventh_chord, 10), “Bb:maj”, circshift(major_chord, 10), “D:min”, circshift(minor_chord, 2), “F:7”, circshift(seventh_chord, 5), “F:maj”, circshift(major_chord, 5), “A:min”, circshift(minor_chord, 9), “C:7”, circshift(seventh_chord, 0), “C:maj”, circshift(major_chord, 0), “E:min”, circshift(minor_chord, 4), “G:7”, circshift(seventh_chord, 7), “G:maj”, circshift(major_chord, 7), “B:min”, circshift(minor_chord, 11), “D:7”, circshift(seventh_chord, 2), “D:maj”, circshift(major_chord, 2), “F#:min”, circshift(minor_chord, 6), “A:7”, circshift(seventh_chord, 9), “A:maj”, circshift(major_chord, 9), “C#:min”, circshift(minor_chord, 1), “E:7”, circshift(seventh_chord, 4), “E:maj”, circshift(major_chord, 4), “G#:min”, circshift(minor_chord, 8), “B:7”, circshift(seventh_chord, 11), “B:maj”, circshift(major_chord, 11), “D#:min”, circshift(minor_chord, 3) )
key_templates <- tribble( ~name, ~template, “Gb:maj”, circshift(major_key, 6), “Bb:min”, circshift(minor_key, 10), “Db:maj”, circshift(major_key, 1), “F:min”, circshift(minor_key, 5), “Ab:maj”, circshift(major_key, 8), “C:min”, circshift(minor_key, 0), “Eb:maj”, circshift(major_key, 3), “G:min”, circshift(minor_key, 7), “Bb:maj”, circshift(major_key, 10), “D:min”, circshift(minor_key, 2), “F:maj”, circshift(major_key, 5), “A:min”, circshift(minor_key, 9), “C:maj”, circshift(major_key, 0), “E:min”, circshift(minor_key, 4), “G:maj”, circshift(major_key, 7), “B:min”, circshift(minor_key, 11), “D:maj”, circshift(major_key, 2), “F#:min”, circshift(minor_key, 6), “A:maj”, circshift(major_key, 9), “C#:min”, circshift(minor_key, 1), “E:maj”, circshift(major_key, 4), “G#:min”, circshift(minor_key, 8), “B:maj”, circshift(major_key, 11), “D#:min”, circshift(minor_key, 3) )
emotions <- get_tidy_audio_analysis(“0cELvuwJW1acISUHYB6suj”) |> compmus_align(sections, segments) |> select(sections) |> unnest(sections) |> mutate( pitches = map(segments, compmus_summarise, pitches, method = “mean”, norm = “manhattan” ) ) emotions |> compmus_match_pitch_template( key_templates, # Change to chord_templates if descired method = “euclidean”, # Try different distance metrics norm = “manhattan” # Try different norms ) |> ggplot( aes(x = start + duration / 2, width = duration, y = name, fill = d) ) + geom_tile() + scale_fill_viridis_c(guide = “none”) + theme_minimal() + labs(x = “Time (s)”, y = ““)
library(tidyverse) library(spotifyr) library(compmus) library(conflicted)
circshift <- function(v, n) { if (n == 0) v else c(tail(v, n), head(v, -n)) }
major_chord <- c( 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0) minor_chord <- c( 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0) seventh_chord <- c( 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0)
major_key <- c(6.35, 2.23, 3.48, 2.33, 4.38, 4.09, 2.52, 5.19, 2.39, 3.66, 2.29, 2.88) minor_key <- c(6.33, 2.68, 3.52, 5.38, 2.60, 3.53, 2.54, 4.75, 3.98, 2.69, 3.34, 3.17)
chord_templates <- tribble( ~name, ~template, “Gb:7”, circshift(seventh_chord, 6), “Gb:maj”, circshift(major_chord, 6), “Bb:min”, circshift(minor_chord, 10), “Db:maj”, circshift(major_chord, 1), “F:min”, circshift(minor_chord, 5), “Ab:7”, circshift(seventh_chord, 8), “Ab:maj”, circshift(major_chord, 8), “C:min”, circshift(minor_chord, 0), “Eb:7”, circshift(seventh_chord, 3), “Eb:maj”, circshift(major_chord, 3), “G:min”, circshift(minor_chord, 7), “Bb:7”, circshift(seventh_chord, 10), “Bb:maj”, circshift(major_chord, 10), “D:min”, circshift(minor_chord, 2), “F:7”, circshift(seventh_chord, 5), “F:maj”, circshift(major_chord, 5), “A:min”, circshift(minor_chord, 9), “C:7”, circshift(seventh_chord, 0), “C:maj”, circshift(major_chord, 0), “E:min”, circshift(minor_chord, 4), “G:7”, circshift(seventh_chord, 7), “G:maj”, circshift(major_chord, 7), “B:min”, circshift(minor_chord, 11), “D:7”, circshift(seventh_chord, 2), “D:maj”, circshift(major_chord, 2), “F#:min”, circshift(minor_chord, 6), “A:7”, circshift(seventh_chord, 9), “A:maj”, circshift(major_chord, 9), “C#:min”, circshift(minor_chord, 1), “E:7”, circshift(seventh_chord, 4), “E:maj”, circshift(major_chord, 4), “G#:min”, circshift(minor_chord, 8), “B:7”, circshift(seventh_chord, 11), “B:maj”, circshift(major_chord, 11), “D#:min”, circshift(minor_chord, 3) )
key_templates <- tribble( ~name, ~template, “Gb:maj”, circshift(major_key, 6), “Bb:min”, circshift(minor_key, 10), “Db:maj”, circshift(major_key, 1), “F:min”, circshift(minor_key, 5), “Ab:maj”, circshift(major_key, 8), “C:min”, circshift(minor_key, 0), “Eb:maj”, circshift(major_key, 3), “G:min”, circshift(minor_key, 7), “Bb:maj”, circshift(major_key, 10), “D:min”, circshift(minor_key, 2), “F:maj”, circshift(major_key, 5), “A:min”, circshift(minor_key, 9), “C:maj”, circshift(major_key, 0), “E:min”, circshift(minor_key, 4), “G:maj”, circshift(major_key, 7), “B:min”, circshift(minor_key, 11), “D:maj”, circshift(major_key, 2), “F#:min”, circshift(minor_key, 6), “A:maj”, circshift(major_key, 9), “C#:min”, circshift(minor_key, 1), “E:maj”, circshift(major_key, 4), “G#:min”, circshift(minor_key, 8), “B:maj”, circshift(major_key, 11), “D#:min”, circshift(minor_key, 3) )
virgos_groove <- get_tidy_audio_analysis(“0Fl4eWzVaMUOdXcOrj6F1q”) |> compmus_align(sections, segments) |> select(sections) |> unnest(sections) |> mutate( pitches = map(segments, compmus_summarise, pitches, method = “mean”, norm = “manhattan” ) ) virgos_groove |> compmus_match_pitch_template( key_templates, # Change to chord_templates if descired method = “euclidean”, # Try different distance metrics norm = “manhattan” # Try different norms ) |> ggplot( aes(x = start + duration / 2, width = duration, y = name, fill = d) ) + geom_tile() + scale_fill_viridis_c(guide = “none”) + theme_minimal() + labs(x = “Time (s)”, y = ““)
library(tidyverse) library(spotifyr) library(compmus) library(conflicted)
circshift <- function(v, n) { if (n == 0) v else c(tail(v, n), head(v, -n)) }
major_chord <- c( 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0) minor_chord <- c( 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0) seventh_chord <- c( 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0)
major_key <- c(6.35, 2.23, 3.48, 2.33, 4.38, 4.09, 2.52, 5.19, 2.39, 3.66, 2.29, 2.88) minor_key <- c(6.33, 2.68, 3.52, 5.38, 2.60, 3.53, 2.54, 4.75, 3.98, 2.69, 3.34, 3.17)
chord_templates <- tribble( ~name, ~template, “Gb:7”, circshift(seventh_chord, 6), “Gb:maj”, circshift(major_chord, 6), “Bb:min”, circshift(minor_chord, 10), “Db:maj”, circshift(major_chord, 1), “F:min”, circshift(minor_chord, 5), “Ab:7”, circshift(seventh_chord, 8), “Ab:maj”, circshift(major_chord, 8), “C:min”, circshift(minor_chord, 0), “Eb:7”, circshift(seventh_chord, 3), “Eb:maj”, circshift(major_chord, 3), “G:min”, circshift(minor_chord, 7), “Bb:7”, circshift(seventh_chord, 10), “Bb:maj”, circshift(major_chord, 10), “D:min”, circshift(minor_chord, 2), “F:7”, circshift(seventh_chord, 5), “F:maj”, circshift(major_chord, 5), “A:min”, circshift(minor_chord, 9), “C:7”, circshift(seventh_chord, 0), “C:maj”, circshift(major_chord, 0), “E:min”, circshift(minor_chord, 4), “G:7”, circshift(seventh_chord, 7), “G:maj”, circshift(major_chord, 7), “B:min”, circshift(minor_chord, 11), “D:7”, circshift(seventh_chord, 2), “D:maj”, circshift(major_chord, 2), “F#:min”, circshift(minor_chord, 6), “A:7”, circshift(seventh_chord, 9), “A:maj”, circshift(major_chord, 9), “C#:min”, circshift(minor_chord, 1), “E:7”, circshift(seventh_chord, 4), “E:maj”, circshift(major_chord, 4), “G#:min”, circshift(minor_chord, 8), “B:7”, circshift(seventh_chord, 11), “B:maj”, circshift(major_chord, 11), “D#:min”, circshift(minor_chord, 3) )
key_templates <- tribble( ~name, ~template, “Gb:maj”, circshift(major_key, 6), “Bb:min”, circshift(minor_key, 10), “Db:maj”, circshift(major_key, 1), “F:min”, circshift(minor_key, 5), “Ab:maj”, circshift(major_key, 8), “C:min”, circshift(minor_key, 0), “Eb:maj”, circshift(major_key, 3), “G:min”, circshift(minor_key, 7), “Bb:maj”, circshift(major_key, 10), “D:min”, circshift(minor_key, 2), “F:maj”, circshift(major_key, 5), “A:min”, circshift(minor_key, 9), “C:maj”, circshift(major_key, 0), “E:min”, circshift(minor_key, 4), “G:maj”, circshift(major_key, 7), “B:min”, circshift(minor_key, 11), “D:maj”, circshift(major_key, 2), “F#:min”, circshift(minor_key, 6), “A:maj”, circshift(major_key, 9), “C#:min”, circshift(minor_key, 1), “E:maj”, circshift(major_key, 4), “G#:min”, circshift(minor_key, 8), “B:maj”, circshift(major_key, 11), “D#:min”, circshift(minor_key, 3) )
higher <- get_tidy_audio_analysis(“1KnJwhZU3DIBe54Q4HPpIl”) |> compmus_align(sections, segments) |> select(sections) |> unnest(sections) |> mutate( pitches = map(segments, compmus_summarise, pitches, method = “mean”, norm = “manhattan” ) ) higher |> compmus_match_pitch_template( key_templates, # Change to chord_templates if descired method = “euclidean”, # Try different distance metrics norm = “manhattan” # Try different norms ) |> ggplot( aes(x = start + duration / 2, width = duration, y = name, fill = d) ) + geom_tile() + scale_fill_viridis_c(guide = “none”) + theme_minimal() + labs(x = “Time (s)”, y = ““)
{r}